package org.snowin.utils;

import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;
import org.apache.log4j.Logger;

import javax.swing.text.html.HTML;
import javax.tools.*;
import java.io.File;
import java.io.Writer;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class JavaCompilerTool {
    private static Logger logger;
    private static String sp = GlobalInfo.getFileSeparator();
    private static JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
    private static URLClassLoader urlClassLoader;
    private static URL[] urls;
    private static Method addURL = initAddMethod();
    private static boolean isDebug = false;
    private Iterable<String> options = null;
    private String targetDir = GlobalInfo.getRootPath() + sp + "bin" + sp + "webuicaseclasses";
    private final String sourceDir = GlobalInfo.getRootPath() + sp + "wtdwebuicases";

    private StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
    private DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<>();
    String jars = "";

    public JavaCompilerTool(URLClassLoader urlClassLoader) {
        logger = Logger.getRootLogger();
        jars = getJarFiles();
        options = Arrays.asList(new String[]{"-encoding", "UTF-8", "-classpath", this.jars, "-d", targetDir, "-sourcepath", sourceDir});
        if (urlClassLoader != null) {
            this.urlClassLoader = urlClassLoader;
        } else {
            try {
                urls = new URL[]{new URL("file:/" + targetDir)};
                urlClassLoader = new URLClassLoader(urls);
                this.isDebug = true;
            } catch (MalformedURLException e) {
                e.printStackTrace();
            }
        }
        try {
            addURL(new File(GlobalInfo.getRootPath() + sp + "bin" + sp + "webuicaseclasses"));
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private void addURL(File file) {
        try {
            addURL.invoke(urlClassLoader, new Object[]{file.toURI().toURL()});
//            logger.info("addURL.invoke() >>>: "+invoke);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static Method initAddMethod() {
        try {
            Method add = URLClassLoader.class.getDeclaredMethod("addURL", new Class[]{URL.class});
            add.setAccessible(true);
            return add;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static URLClassLoader getClassLoader() {
        return urlClassLoader;
    }

    public void setClassLoader(URLClassLoader classLoader) {
        urlClassLoader = classLoader;
    }

    public boolean comiple(String targetDir, String sourceFile) {

        if (targetDir == null || targetDir.isEmpty()) {
            this.targetDir = targetDir;
        }

        boolean status = false;
        Iterable<? extends JavaFileObject> compilationUnits = this.fileManager.getJavaFileObjects(new File[]{new File(sourceFile)});
        try {
            if ((this.jars == null) || (this.jars.trim() == "")) {


                int statusInt = compiler.run(null, null, null, new String[]{"-d", targetDir, sourceFile});
                if (statusInt == 0) {
                    status = true;
                } else {
                    status = false;
                }
            } else {

                status = compiler.getTask(null, this.fileManager, this.diagnostics, this.options, null, compilationUnits).call();
                if (!status){
                    int statusInt = compiler.run(null, null, null, new String[]{"-d", targetDir, sourceFile});
                    if (statusInt == 0) {
                        status = true;
                    } else {
                        status = false;
                    }
                }
            }
        } catch (Exception e) {
            if (e.getClass().getSimpleName().equals("NullPointerException")) {
                System.out.println("请将本机jdk/lib中的tool.jar拷贝到%JAVA_HOME%/jre/lib中");
            } else {
                e.printStackTrace();
            }
        }
        return status;
    }


    public String getJarFiles() {
        File libDir = new File(GlobalInfo.getRootPath() + sp + "lib");
        List<String> includeJarFiles = new ArrayList();
        String jars = "";
        includeJarFiles.add("wtd.jar");
        includeJarFiles.add("dom4j-1.6.1.jar");
        includeJarFiles.add("jaxen-1.1.1.jar");
        includeJarFiles.add("log4j-1.2.17.jar");
        includeJarFiles.add("selenium-server-standalone-2.53.0.jar");
        includeJarFiles.add("activation-1.1.1.jar");
        includeJarFiles.add("javax.mail-1.5.6.jar");
        includeJarFiles.add("mysql-connector-java-5.0.5.jar");
        includeJarFiles.add("substance-7.3.jar");
        includeJarFiles.add("trident-1.3.jar");
        includeJarFiles.add("trident-7.3-swing.jar");
        File[] files;
        try {

            files = libDir.listFiles();
        } catch (Exception e) {
            throw new BaseException("GetJarFiles() Method  fetcher null");
        }
        for (File file : files
                ) {
            if (includeJarFiles.contains(file.getName())) {
                jars = jars + file.getPath() + ";";
            }

        }
        return jars;
    }
}
